package top.jacktgq.imooc.groupchat;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
import top.jacktgq.utils.LogUtils;
/**
 * @Title: ChatHandler.java 
 * @Package top.jacktgq.imooc.groupchat 
 * @Description: 处理WebSocket消息的Handler
 *                  TextWebSocketFrame：在Netty中，是用于为WebSocket专门处理文本的对象，frame是消息的载体
 * @author CandyWall   
 * @date 2021年2月4日 下午10:19:57 
 * @version V1.0
 */
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    // 用于记录和管理所有客户端的Channel
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); 
    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        // 获取客户端传输过来的消息
        String content = msg.text();
        System.out.println("接收到的数据：" + content);
        TextWebSocketFrame responseMsg = new TextWebSocketFrame("服务器时间：" + LogUtils.getCurrentTime() + " " + msg.text());
        // 只能flush一次
        /*for(Channel channel : channelGroup) {
            channel.writeAndFlush(responseMsg);
        }*/
        channelGroup.writeAndFlush(responseMsg);
    }
    
    //当web客户端连接后，就会触发方法
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        System.out.println("有新的WebSocket客户端接入：LongText：" + ctx.channel().id().asLongText() + "，ShortText：" + ctx.channel().id().asShortText());
        // 获取客户端的Channel，并且放到ChannelGroup中进行管理
        channelGroup.add(ctx.channel());
    }

    //当web客户端断开连接后，就会触发该方法
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        System.out.println("WebSocket客户端断开：长ID：" + ctx.channel().id().asLongText() + "短ID：" + ctx.channel().id().asShortText());
        // channelGroup.remove(ctx.channel());
        // 这里不需要自己去把当前的channel从channelGroup中移除，netty内部已经实现
        // 当触发handlerRemoved，ChannelGroup内部会自动移除对应客户端的channel
        System.out.println("Before Remove channelGroup.size() = " + channelGroup.size());
        // channelGroup.remove(ctx.channel());
        // System.out.println("After Remove channelGroup.size() = " + channelGroup.size());
    }
    
}
